package com.example.intermingle.service;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.example.intermingle.Constants;
import com.example.intermingle.dto.JqGridPageDto;
import com.example.intermingle.dto.ResourcesDto;
import com.example.intermingle.dto.ResourcesEditAndDelDto;
import com.example.intermingle.mapper.ResourcesMapper;
import com.example.intermingle.mapper.RoleResourcesMapper;
import com.example.intermingle.util.CommonUtils;
import com.example.intermingle.util.UserUtils;
import com.example.intermingle.vo.Resources;
import com.example.intermingle.vo.Role;
import com.example.intermingle.vo.RoleResources;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * @author 绿松石
 * @version V1.0
 * @Title ResourcesService
 * @Description
 * @date 2021年08月27日 09:51
 * @since V1.0
 */
@Service
public class ResourcesService {

    @Autowired
    ResourcesMapper resourcesMapper;

    @Autowired
    RoleResourcesMapper roleResourcesMapper;

    public List<ResourcesDto> selectResources() {
        List<ResourcesDto> resources=resourcesMapper.selectResources(UserUtils.getCurrentHr().getUserId());
        System.out.println("权限是："+JSON.toJSON(resources));
        return  resources;
    }

    /**
     * 查询所有的资源，因为删除和更改角色资源，前端页面没法传递角色id，提前把角色id封装到查询所有的方法
     * @param roleId
     * @return
     */
    public JqGridPageDto<ResourcesEditAndDelDto> selectRoleResources(Integer roleId) {
        //定义一个对象
        JqGridPageDto<ResourcesEditAndDelDto> resourcesEditAndDelDtoJqGridPageDto=new JqGridPageDto<>();

        //定义一个对象
        List<ResourcesEditAndDelDto> resourcesEditAndDelDtoList=new ArrayList<>();
        //查询出来所有的资源信息
       List<Resources> resourcesList=resourcesMapper.selectAllResources();
       //对查出来的资源数据进行循环
       for(int i=0;i<resourcesList.size();i++){
           //定义一个对象
           ResourcesEditAndDelDto resourcesEditAndDelDto=new ResourcesEditAndDelDto();
           //赋值
           resourcesEditAndDelDto.setRoleId(roleId);
           resourcesEditAndDelDto.setResourcesName(resourcesList.get(i).getResourcesName());
           resourcesEditAndDelDto.setResourcesId(resourcesList.get(i).getResourcesId());
           resourcesEditAndDelDto.setUrl(resourcesList.get(i).getUrl());
           resourcesEditAndDelDto.setPath(resourcesList.get(i).getPath());
           resourcesEditAndDelDto.setComponent(resourcesList.get(i).getComponent());
           //把对象加入到list集合
           resourcesEditAndDelDtoList.add(resourcesEditAndDelDto);
       }
       //赋值
       resourcesEditAndDelDtoJqGridPageDto.setRows(resourcesEditAndDelDtoList);
       return  resourcesEditAndDelDtoJqGridPageDto;

    }

    /**
     * 根据id查询单个角色所拥有的资源
     * @param roleId
     * @return
     */
    public JqGridPageDto<Resources> selectSingleRoleResources(Integer roleId) {
        //定义一个对象
        JqGridPageDto<Resources> resourcesJqGridPageDto=new JqGridPageDto<>();
        //用角色id来查询资源信息
        List<Resources> resourcesList=resourcesMapper.selectSingleRoleResources(roleId);
        //赋值返回
        resourcesJqGridPageDto.setRows(resourcesList);
        return resourcesJqGridPageDto;

    }

    /**
     * 根据角色id系新增资源，（该该方法把传过来的资源数据和查到的数据库数据做对比，然后放到resourcesLists
     *  ，批量添加）
     * @param roleEditAndDelDtos 传过来的资源信息
     * @return
     */
    public JqGridPageDto<Resources> addRoleResources(List<ResourcesEditAndDelDto> roleEditAndDelDtos) {
        //定义一个对象
        JqGridPageDto<Resources> resourcesJqGridPageDto=new JqGridPageDto<>();
        //定义一个对象
        Collection<RoleResources> resourcesLists=new ArrayList<>();
        //判空
        if(roleEditAndDelDtos.isEmpty()){
            resourcesJqGridPageDto.setErrorMsg(Constants.FAILCode.ADD_FAIL);
        }else{
            //查询角色的资源信息
            List<Resources> resourcesList=resourcesMapper.selectSingleRoleResources(roleEditAndDelDtos.get(0).getRoleId());
            for(int i=0;i<roleEditAndDelDtos.size();i++){
                //如果查询的结果为空，直接添加资源
                if(resourcesList.isEmpty()){
                    //不一致的权限添加到rolsList,切记，该list存放的是从数据库查出来的角色信息
                    RoleResources roleResources=new RoleResources();
                    roleResources.setResourcesId(roleEditAndDelDtos.get(i).getResourcesId());
                    roleResources.setRoleId(roleEditAndDelDtos.get(i).getRoleId());
                    roleResources.setCreatedBy(CommonUtils.getName());
                    roleResources.setCreatedDate(new Date());
                    roleResources.setUpdateBy(CommonUtils.getName());
                    roleResources.setUpdateDate(new Date());
                    //跟删除是相反的
                    resourcesLists.add(roleResources);
                }else{
                    int frequency=1;
                    //根据用户id查询出来的用户信息进行循环，如果添加的数据已经存在则忽略，不存在则添加
                    for(int j=0;j<resourcesList.size();j++){

                        //判断取到的权限不一致
                        if(roleEditAndDelDtos.get(i).getResourcesId().equals(resourcesList.get(j).getResourcesId())){
                            frequency=0;
                        }
                    }
                    if(frequency==1){
                        //不一致的权限添加到rolsList,切记，该list存放的是从数据库查出来的角色信息
                        RoleResources roleResources=new RoleResources();
                        roleResources.setResourcesId(roleEditAndDelDtos.get(i).getResourcesId());
                        roleResources.setRoleId(roleEditAndDelDtos.get(i).getRoleId());
                        roleResources.setCreatedBy(CommonUtils.getName());
                        roleResources.setCreatedDate(new Date());
                        roleResources.setUpdateBy(CommonUtils.getName());
                        roleResources.setUpdateDate(new Date());
                        //跟删除是相反的
                        resourcesLists.add(roleResources);
                    }
                }
            }
        }
        int count=0;
        if(!resourcesLists.isEmpty()){
            count =roleResourcesMapper.insertBatch(resourcesLists );

        }
        if(count!=0){
            resourcesJqGridPageDto.setErrorMsg(Constants.SUCCESSCode.ADD_SUCCESS);
        }else {
            resourcesJqGridPageDto.setErrorMsg(Constants.FAILCode.ADD_FAIL);
        }
        return resourcesJqGridPageDto;
    }
    /**
     * 根据角色id系删除资源，（该方法把传过来的资源数据和查到的数据库数据做对比，然后放到resourcesLists
     * ，依次删除）
     * @param roleEditAndDelDtos 传过来的资源信息
     * @return
     */
    public JqGridPageDto<Resources> delRoleResources(List<ResourcesEditAndDelDto> roleEditAndDelDtos) {
        //定义一个对象
        JqGridPageDto<Resources> resourcesJqGridPageDto=new JqGridPageDto<>();
        //定义一个对象
        List<RoleResources> resourcesLists=new ArrayList<>();
        //判空
        if(roleEditAndDelDtos.isEmpty()){
            resourcesJqGridPageDto.setErrorMsg(Constants.FAILCode.DELECT_FAIL);
        }else{
            //查询角色的资源信息
            List<Resources> resourcesList=resourcesMapper.selectSingleRoleResources(roleEditAndDelDtos.get(0).getRoleId());
            for(int i=0;i<resourcesList.size();i++){
                if(resourcesList.isEmpty()){
                    resourcesJqGridPageDto.setErrorMsg(Constants.FAILCode.DELECT_FAIL);
                    return  resourcesJqGridPageDto;
                }else{
                    int frequency=1;
                    //根据用户id查询出来的用户信息
                    for(int j=0;j<roleEditAndDelDtos.size();j++){
                        //判断取到的权限不一致
                        if(roleEditAndDelDtos.get(j).getResourcesId().equals(resourcesList.get(i).getResourcesId())){
                            frequency=0;
                        }
                        if(frequency==1){
                            //定义一个对象
                            RoleResources roleResources=new RoleResources();
                            roleResources.setResourcesId(resourcesList.get(i).getResourcesId());
                            //加入list集合
                            resourcesLists.add(roleResources);


                        }
                    }

                }
            }
        }
        String text="";
        //for循环删除权限
        for(int i=0;i<resourcesLists.size();i++){
            //根据用户id和角色id来查询用户角色权限
            RoleResources roleResources=roleResourcesMapper.selectOneByRoleIdAndResourcesId(roleEditAndDelDtos.get(0).getRoleId(),resourcesLists.get(i).getResourcesId());
            //判断对象userRole不为空
            if(roleResources!=null){
                //不为空进行删除角色权限信息
                int count =roleResourcesMapper.delByRoleResourcesId(roleResources.getRoleResourcesId());
                if(count==1){
                    text=text+","+"资源id："+resourcesLists.get(i).getResourcesId()+Constants.SUCCESSCode.DELECT_SUCCESS;
                }else{
                    text=text+","+"资源id："+resourcesLists.get(i).getResourcesId()+Constants.FAILCode.DELECT_FAIL;
                }
            }
        }
        resourcesJqGridPageDto.setErrorMsg(text);

        return resourcesJqGridPageDto;
    }

    /**
     * 查询所有的资源数据
     * @param page
     * @param size
     * @param resourcesId
     * @param resourcesName
     * @return
     */
    public JqGridPageDto<Resources> selectResourcex(Integer page, Integer size, Integer resourcesId, String resourcesName) {
        if (page != null && size != null) {
            page = (page - 1) * size;
        }
        //根据条件查询所有数据
        List<Resources> resourcesList=resourcesMapper.selectAllResourcex(page,size,resourcesId,resourcesName);
        //查询总页数
        Long records=resourcesMapper.getTotal(resourcesId,resourcesName);
        JqGridPageDto<Resources> resourcesJqGridPageDto=new JqGridPageDto<>();
        resourcesJqGridPageDto.setRecords(records);
        resourcesJqGridPageDto.setRows(resourcesList);
        return resourcesJqGridPageDto;
    }

    /**
     * 增加数据
     * @param resources
     * @return
     */
    public JqGridPageDto<Resources> addResources(Resources resources) {
        //定义一个对象
        JqGridPageDto<Resources> resourcesJqGridPageDto=new JqGridPageDto<>();
        //赋值
        resources.setCreatedBy(CommonUtils.getName());
        resources.setUpdateBy(CommonUtils.getName());
        resources.setCreatedDate(new Date());
        resources.setUpdateDate(new Date());
        int count =resourcesMapper.addAll(resources);
        //判断是否成功
        if(count==1){
            //赋值
            resourcesJqGridPageDto.setErrorMsg(Constants.SUCCESSCode.ADD_SUCCESS);
        }else{
            //赋值
            resourcesJqGridPageDto.setErrorMsg(Constants.FAILCode.ADD_FAIL);
        }
        return  resourcesJqGridPageDto;
    }

    /**
     * 修改数据
     * @param resources
     * @return
     */
    public JqGridPageDto<Resources> updateResources(Resources resources) {
        //定义一个对象
        JqGridPageDto<Resources> resourcesJqGridPageDto=new JqGridPageDto<>();
        //赋值
        resources.setUpdateBy(CommonUtils.getName());
        resources.setUpdateDate(new Date());
        int count =resourcesMapper.updateAllResources(resources);
        //判断是否成功
        if(count==1){
            //赋值
            resourcesJqGridPageDto.setErrorMsg(Constants.SUCCESSCode.UPDATE_SUCCESS);
        }else{
            //赋值
            resourcesJqGridPageDto.setErrorMsg(Constants.FAILCode.UPDATE_FAIL);
        }
        return  resourcesJqGridPageDto;
    }

    /**
     * 删除资源
     * @param resourcesId
     * @return
     */
    public JqGridPageDto<Resources> delResources(Integer resourcesId) {
        int count=resourcesMapper.delByResourcesId(resourcesId);
        JqGridPageDto<Resources> resourcesJqGridPageDto=new JqGridPageDto<>();
        if(count==1){
            //赋值
            resourcesJqGridPageDto.setErrorMsg(Constants.SUCCESSCode.DELECT_SUCCESS);
        }else{
            //赋值
            resourcesJqGridPageDto.setErrorMsg(Constants.FAILCode.DELECT_FAIL);
        }
        return  resourcesJqGridPageDto;
    }

    /**
     * 导入角色
     * @param request
     * @return
     */
    public JqGridPageDto<Resources> imporResources(HttpServletRequest request) {
        //定义一个对象
        JqGridPageDto<Resources> resourcesJqGridPageDto=new JqGridPageDto<>();
        //定义一个MultipartHttpServletRequest对象
        MultipartHttpServletRequest multipartRequest =null;
        //判断里面有没有文件
        if (request instanceof MultipartHttpServletRequest) {
            multipartRequest = (MultipartHttpServletRequest)(request);
        }
        //统计导入成功数
        int successCount=0;
        //统计导入失败数
        int failCount=0;
        //获取文件流，写入list集合
        List<MultipartFile> files = multipartRequest.getFiles("file");
        //存在多个文件，用for循环
        for(int i=0;i<files.size();i++){
            try {
                //写入字节输入流
                InputStream inputStream=files.get(i).getInputStream();
                ExcelReader excelReader= ExcelUtil.getReader(inputStream,"sheet1");
                //加入表头名称和封装对象的名称
                excelReader.addHeaderAlias("url","url");
                excelReader.addHeaderAlias("路径","path");
                excelReader.addHeaderAlias("成分","component");
                excelReader.addHeaderAlias("资源名称","resourcesName");
                excelReader.addHeaderAlias("图标","iconcls");
                excelReader.addHeaderAlias("节点","parentid");
                excelReader.addHeaderAlias("启用","enabled");
                excelReader.addHeaderAlias("授权","requireauth");

                //获取文档的内容
                List<Resources> resourcesx=excelReader.readAll(Resources.class);
                String error=checkResourcesImport(resourcesx);
                if(!error.equals(null)){
                    resourcesJqGridPageDto.setErrorMsg(error);
                    return  resourcesJqGridPageDto;
                }
                for(int j=0;j<resourcesx.size();j++){
                    //定义一个角色对象
                    Resources resources=new Resources();
                    //赋值
                    resources.setUrl(resourcesx.get(j).getUrl());
                    resources.setPath(resourcesx.get(j).getPath());
                    resources.setComponent(resourcesx.get(j).getComponent());
                    resources.setResourcesName(resourcesx.get(j).getResourcesName());
                    resources.setIconcls(resourcesx.get(j).getIconcls());
                    resources.setParentid(resourcesx.get(j).getParentid());
                    resources.setEnabled(resourcesx.get(j).getEnabled());
                    resources.setRequireauth(resourcesx.get(j).getRequireauth());
                    resources.setCreatedBy(CommonUtils.getName());
                    resources.setUpdateBy(CommonUtils.getName());;
                    resources.setCreatedDate(new Date());
                    resources.setUpdateDate(new Date());
                    int count=resourcesMapper.addAll(resources);
                    //插入成功
                    if(count==1){
                        //成功次数加1
                        successCount=successCount+1;
                    }else{
                        //失败次数加1
                        failCount=failCount+1;
                    }
                }
                resourcesJqGridPageDto.setErrorMsg("导入数"+(successCount+failCount)+"成功条数"+successCount+"失败条数"+failCount);
            }catch (Exception e){
                resourcesJqGridPageDto.setErrorMsg("导入失败");
            }
        }
        return resourcesJqGridPageDto;
    }

    /**
     * 角色导出
     * @param page
     * @param size
     * @param response
     */
    public void exportResources(Integer page, Integer size, HttpServletResponse response) {
        if (page != null && size != null) {
            page = (page - 1) * size;
        }
        //根据条件查询角色信息
        List<Resources> resources=resourcesMapper.selectAllResourcex(page,size,null,null);

        //模板名称
        String fileName=Constants.TEMPLATE_EXPORT_RESOURCES;
        //创建一个ExcelWriter
        ExcelWriter writer = ExcelUtil.getWriter(true);
        //给字段标值

        writer.addHeaderAlias("resourcesId","资源id");
        writer.addHeaderAlias("url","url");
        writer.addHeaderAlias("path","路径");
        writer.addHeaderAlias("component","成分");
        writer.addHeaderAlias("resourcesName","资源名称");
        writer.addHeaderAlias("iconcls","图标");
        writer.addHeaderAlias("parentid","节点");
        writer.addHeaderAlias("enabled","启用");
        writer.addHeaderAlias("requireauth","授权");
        writer.addHeaderAlias("createdBy","创建人员");
        writer.addHeaderAlias("updateBy","更新人员");
        writer.addHeaderAlias("createdDate","创建时间");
        writer.addHeaderAlias("updateDate","修改时间");
        writer.write(resources, true);
        try {
            // 获取我们的输出流
            final OutputStream output = response.getOutputStream();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";filename*=utf-8''"
                    + URLEncoder.encode(fileName, Constants.CODING_UTF8));
            writer.flush(output, true);
            writer.close();
            output.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * 校验角色导入数据
     * @param resources
     * @return
     */
    private String checkResourcesImport(List<Resources> resources){
        //url错误信息
        String urlError="";
        //路径错误信息
        String pathError="";
        //成分错误信息
        String componentError="";
        //资源名称错误信息
        String resourcesNameError="";
        //角色权限错误信息
        String parentidError="";

        for(int i=0;i<resources.size();i++){
            if (!CommonUtils.isNotNull(resources.get(i).getUrl())){
                urlError=Constants.importCheck.RESOURCESIMPORT_RESOURCES_URL;
            }
            if (!CommonUtils.isNotNull(resources.get(i).getPath())){
                pathError=Constants.importCheck.RESOURCESIMPORT_RESOURCES_PATH;
            }
            if (!CommonUtils.isNotNull(resources.get(i).getComponent())){
                componentError=Constants.importCheck.RESOURCESIMPORT_RESOURCES_COMPONENT;
            }
            if (!CommonUtils.isNotNull(resources.get(i).getResourcesName())){
                resourcesNameError=Constants.importCheck.RESOURCESIMPORT_RESOURCES_RESOURCESNAME;
            }
            if (!CommonUtils.isNotNull(resources.get(i).getParentid())){
                parentidError=Constants.importCheck.RESOURCESIMPORT_RESOURCES_PARENTID;
            }


        }
        //两个错误信息都没有。直接返回null
        if(!urlError.isEmpty()&&!pathError.isEmpty()&&!componentError.isEmpty()&&!resourcesNameError.isEmpty()&&!parentidError.isEmpty()){
            return  urlError+pathError+componentError+resourcesNameError+parentidError;
        }
        return   null;

    }
}
